﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Resources;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using System.Text.RegularExpressions;

namespace Ue.Components.FileResources
{
    public class XmlResourceWriter : IResourceWriter
    {
        private string fileName;
        private XmlElement root;

        public XmlResourceWriter(string fileName)
        {
            this.fileName = fileName;
            this.Document = new XmlDocument();
            this.Document.AppendChild(this.Document.CreateXmlDeclaration("1.0", "utf-8", null));
            this.root = this.Document.CreateElement("resources");
            this.Document.AppendChild(this.root);
        }

        public XmlDocument Document { get; private set; }

        public void AddResource(string name, byte[] value)
        {
            throw new NotImplementedException();
        }

        public void AddResource(string name, object value)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            var nodeInnerXml = string.Empty;
            var objectType = value.GetType();

            XmlSerializer serializer = new XmlSerializer(objectType);
            using (StringWriter writer = new StringWriter())
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add(string.Empty, string.Empty);

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.OmitXmlDeclaration = true;

                serializer.Serialize(writer, value, ns);

                nodeInnerXml = Regex.Replace(writer.ToString(), @"<\?xml[^>].*>", string.Empty);
            }

            var firstWhitespaceIndex = nodeInnerXml.IndexOf(' ');
            nodeInnerXml = nodeInnerXml.Insert(firstWhitespaceIndex + 1, string.Format("name=\"{0}\" type=\"{1}\" ", name, objectType.AssemblyQualifiedName));

            this.root.InnerXml += nodeInnerXml;
        }

        public void AddResource(string name, string value)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            var node = this.Document.CreateElement("add");
            node.SetAttribute("name", name);
            node.SetAttribute("value", value);
            this.root.AppendChild(node);
        }

        public void Generate()
        {
            using (XmlWriter writer = new XmlTextWriter(this.fileName, Encoding.UTF8))
            {
                this.Document.WriteTo(writer);
            }
        }

        public void Dispose() { }

        public void Close() { }
    }
}
